<template>
  <CommonPage title="操作权限组定义" content-row>
    <div class="flex-1 flex flex-col overflow-hidden">
      <div class="mb-4">
        <a-button type="primary" @click="showCreateModal">新增操作权限组</a-button>
      </div>
      <div class="flex-1 overflow-hidden">
        <SlTable
          :columns="columns"
          row-key="id"
          :data-source="tableData"
          :pagination="pagination"
          :loading="tableLoading"
          :row-selection="{
            type: 'radio',
            selectedRowKeys,
            onChange,
          }"
          :custom-row="customRow"
        >
          <template #bodyCell="{ column, record }">
            <div v-if="column.key === 'oper'">
              <a @click="showUpdateModal(record)">编辑</a>
              <a class="ml-2 text-red-400" @click="handleDelete(record)">删除</a>
            </div>
          </template>
        </SlTable>
      </div>
    </div>
    <div class="w-80 pl-2 flex flex-col">
      <div class="py-2.5 font-semibold text-xl"> {{ curSelRoleName }}操作权限 </div>
      <div
        v-if="authMenuList && authMenuList.length > 0 && curSelRoleName && authMenuIds.length > 0"
        class="flex-1 overflow-auto"
      >
        <a-tree
          :tree-data="authMenuList"
          block-node
          show-line
          default-expand-all
          :field-names="{ title: 'name', key: 'id', children: 'children' }"
        >
        </a-tree>
      </div>
      <div v-else class="flex-1 flex items-center justify-center">
        <SlEmpty :description="curSelRoleName ? '暂无权限' : '请先选择操作权限组'" />
      </div>
    </div>
    <CURDDialog
      id-key="id"
      create-title="新增权限组"
      update-title="编辑权限组"
      delete-message="确认删除该权限组吗？"
      :show-options="showOptions"
      :model="model"
      :model-form-setting="modelFormSetting"
      :table-data="tableData"
      :curd="curd"
      :reload-table="reloadTable"
      :get-detail="getDetail"
      @ok="onOk"
    />
  </CommonPage>
</template>
<script setup lang="ts">
import { computed, h, ref, watch } from "vue";
import { useCURD } from "/@/hooks/useCURD";
import { TableProps } from "ant-design-vue";
import { findParents, loopItem } from "/@/utils/treeData";
import { MenuItem, RoleItem } from "/@/api/main/system/models";
import { getRoleMenuIds, getMenuList } from "/@/api/main/system";
import { Api } from "/@/api/main/system";
import {
  CURDAction,
  CURDModalEvent,
  FormItemComponentType,
  FormItemData,
  ShowCURDModalOptions,
} from "/@/components/CURDDialog/models";
import { PatternKey } from "/@/utils/verify";
import MenuTree from "/@/components/MenuTree.vue";
import { cloneDeep } from "lodash-es";

/**
 * 操作权限组
 */
const columns = ref<TableProps<RoleItem>["columns"]>([
  {
    title: "权限组名称",
    dataIndex: "name",
  },
  {
    title: "权限组编码",
    dataIndex: "code",
  },
  {
    title: "操作",
    key: "oper",
    width: 100,
  },
]);
const { pagination, tableData, tableLoading, curd, reloadTable } = useCURD<RoleItem>({
  getPageUrl: Api.rolesPage,
  cudUrl: Api.roles,
});
const selectedRowKeys = ref<number[]>([]);
function onChange(keys) {
  selectedRowKeys.value = keys;
}
function customRow(record: RoleItem) {
  return {
    onclick: () => {
      selectedRowKeys.value = [record.id];
    },
  };
}
const curSelRoleName = computed(() => {
  if (selectedRowKeys.value.length > 0) {
    const target = tableData.value.find((item) => item.id === selectedRowKeys.value[0]);
    if (target) {
      return target.name;
    }
  }
  return "";
});
/**
 * 增加修改弹窗
 */
const showOptions = ref<ShowCURDModalOptions>();
const model = ref<Partial<RoleItem>>({
  name: "",
  code: "",
  sort: 1,
  menuIds: [],
});
const modelFormSetting: FormItemData<Partial<RoleItem>>[] = [
  {
    key: "name",
    max: 32,
    pattern: PatternKey.name,
    required: true,
    label: "名称",
  },
  {
    key: "code",
    max: 32,
    pattern: PatternKey.code,
    required: true,
    label: "编码",
  },
  {
    key: "sort",
    type: FormItemComponentType.NUMBER,
    props: {
      min: 0,
      max: 999,
    },
    label: "排序值",
  },
  {
    key: "menuIds",
    label: "菜单权限",
    customComponent: h(MenuTree),
    required: true,
    requiredMes: "请选择菜单权限",
  },
];
async function getDetail(record: Partial<RoleItem>) {
  const data = await getRoleMenuIds(record.id as number);
  return {
    menuIds: data || [],
  };
}
function showCreateModal() {
  showOptions.value = { action: CURDAction.CREATE };
}
function showUpdateModal(record) {
  showOptions.value = { action: CURDAction.UPDATE, record };
}
function handleDelete(record) {
  showOptions.value = { action: CURDAction.DELETE, ids: [record.id] };
}
function onOk({ action }: CURDModalEvent) {
  if (action === CURDAction.UPDATE) {
    selectedRowKeys.value = [...selectedRowKeys.value];
  }
}
/**
 * 操作权限
 */
const menuList = ref<MenuItem[]>();
const authMenuIds = ref<number[]>([]);
const authMenuList = ref<MenuItem[]>([]);
watch(selectedRowKeys, async (v) => {
  if (!menuList.value) {
    const data = await getMenuList();
    if (data) {
      menuList.value = data;
    }
  }
  const roleId = v[0];
  const menuIds = await getRoleMenuIds(roleId);
  if (menuIds) {
    authMenuIds.value = [...menuIds];
    if (menuList.value && menuList.value.length > 0 && menuIds.length > 0) {
      const copyData = cloneDeep(menuList.value);
      let ids: number[] = [];
      while (menuIds.length > 0) {
        const menuId = menuIds[0];
        const pIds: number[] = [];
        findParents(copyData, { keyValue: menuId }, pIds);
        ids.push(menuId);
        ids = ids.concat(pIds);
        menuIds.splice(0, 1);
        pIds.forEach((pId) => {
          const index = menuIds.findIndex((id) => id === pId);
          if (index >= 0) {
            menuIds.splice(index, 1);
          }
        });
      }
      loopItem(
        copyData,
        (item, i, items) => {
          if (!ids.includes(item.id)) {
            items.splice(i, 1);
          }
        },
        { isReverse: true }
      );
      authMenuList.value = copyData;
    } else {
      authMenuList.value = [];
    }
  }
});
</script>
